package com.finalproject.entity;

//import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
//import java.util.Scanner;
import java.util.List;

/**
 *  DietaryProfile Class
 * 		assigns default dietary preferences 		DONE
 * 		allows changes to dietary preferences		DONE
 * 		keeps track of preferences					
 * 		updates status with new purchases			DONE
 * 		summary for 
 * 
 *  @author Ballori Sengupta
 *  @author Cagri Akargun
 */
public class DietaryProfile {
	/* remainingPref = , startPref = maxValue, runningTotal = 0 */
	private int maxCals = 2000;//, startCals = 2000, usedCals = 0;					/* cal */
	private int fat = 20;//, startFat = 20, usedFat = 0;				/*  g  */
	private int cholestrol = 300;//, startCholestrol = 300, usedCholestrol = 0;	/* mg  */
	private int sodium = 2400;//, startSodium = 2400, usedSodium = 0; 				/* mg  */
	private int totalCarbs = 300;//, startCarbs = 300, usedCarbs = 0; 				/*  g  */
	private int protein = 50;//, startProtein = 50, usedProtein = 0;				/*  g  */
	
	private LinkedList<DietaryEntry> dietaryHistory=new LinkedList<DietaryEntry>();

	//Observer for the UI
	public interface DietaryProfileObserver {
		public void onUpdate(DietaryProfile dietaryProfile);
	}

	private List<DietaryProfileObserver> dietaryProfileObservers = new ArrayList<DietaryProfileObserver>();

	public DietaryProfile(int maxCals, int fat, int cholestrol, int sodium, int totalCarbs, int protein){
		this.maxCals = maxCals;
		this.fat = fat;
		this.cholestrol = cholestrol;
		this.sodium = sodium;
		this.totalCarbs = totalCarbs;
		this.protein = protein;
		this.dietaryProfileObservers = new ArrayList<DietaryProfileObserver>();
	}

	/** default options */
	public DietaryProfile(){
		this(2000, 20, 300, 2400, 300, 50);			 //default values
		//		maxCals = 2000;
		//		startCals = maxCals;
		//		fat = 20;
		//		startFat = fat;
		//		cholestrol = 300;
		//		startCholestrol = cholestrol;
		//		sodium = 2400;
		//		startSodium = sodium;
		//		totalCarbs = 300;
		//		startCarbs = totalCarbs;
		//		protein = 50;
		//		startProtein = protein;

	}

	public void addDietaryProfileObserver(DietaryProfileObserver dietaryProfileObserver) {
		if(dietaryProfileObservers == null) {
			dietaryProfileObservers  = new ArrayList<DietaryProfile.DietaryProfileObserver>();
		}
		if(!dietaryProfileObservers.contains(dietaryProfileObserver)) {
			dietaryProfileObservers.add(dietaryProfileObserver);
		}
		
	}

	public void removeDietaryProfileObserver(DietaryProfileObserver dietaryProfileObserver) {
		dietaryProfileObservers.remove(dietaryProfileObserver);
	}


	private void fireDietaryProfileObservers(DietaryProfile dietaryProfile) {
		for(DietaryProfileObserver dietaryProfileObserver: dietaryProfileObservers) {
			dietaryProfileObserver.onUpdate(dietaryProfile);
		}
	}


	//public void buyFood(SnackItem item) throws CaloriesExceededException{
	public void buyFood(SnackItem item) throws CaloriesExceededException{
		int cal=item.getCalories();
		Calendar today=Calendar.getInstance();
		if (!dietaryHistory.isEmpty()){
			DietaryEntry tempEntry=dietaryHistory.getLast();
			Calendar tempDay=tempEntry.getDate();

			if ((today.get(Calendar.DAY_OF_MONTH)==tempDay.get(Calendar.DAY_OF_MONTH)) && (today.get(Calendar.MONTH)==tempDay.get(Calendar.MONTH)) && (today.get(Calendar.YEAR)==tempDay.get(Calendar.YEAR))){
				int usedCals=tempEntry.getConsumed();
				//if ((cal+usedCals)>maxCals)
				//	throw new CaloriesExceededException("The calorie limit is exceeded");
				usedCals+=cal;
				dietaryHistory.removeLast();
				dietaryHistory.addLast(new DietaryEntry(today, usedCals,getCalories()));
			}
			else{
				dietaryHistory.addLast(new DietaryEntry(today, cal,getCalories()));
			}
		}
		else{
			dietaryHistory.addLast(new DietaryEntry(today, cal,getCalories()));
		}	
		fireDietaryProfileObservers(this);
	}

	public void buyFood(SnackItem item, Calendar date){
		int cal=item.getCalories();
		if (!dietaryHistory.isEmpty()){
			DietaryEntry tempEntry=dietaryHistory.getFirst();
			Calendar tempDay=tempEntry.getDate();

			if ((date.get(Calendar.DAY_OF_MONTH)==tempDay.get(Calendar.DAY_OF_MONTH)) && (date.get(Calendar.MONTH)==tempDay.get(Calendar.MONTH)) && (date.get(Calendar.YEAR)==tempDay.get(Calendar.YEAR))){
				int usedCals=tempEntry.getConsumed();
				//if ((cal+usedCals)>maxCals)
				//	throw new CaloriesExceededException("The calorie limit is exceeded");
				usedCals+=cal;
				dietaryHistory.remove();
				dietaryHistory.addFirst(new DietaryEntry(date, usedCals,getCalories()));
			}
			else{
				dietaryHistory.addFirst(new DietaryEntry(date, cal,getCalories()));
			}
		}
		else{
			dietaryHistory.addFirst(new DietaryEntry(date, cal,getCalories()));
		}	
		fireDietaryProfileObservers(this);
	}

	public void updatePreference(int calories, int fat, int cholestrol, int sodium, int carbs, int protien) {
		setCalories(calories);
		setFat(fat);
		setCholestrol(cholestrol);
		setSodium(sodium);
		setCarbs(carbs);
		setProtein(protien);
		fireDietaryProfileObservers(this);
		
		System.out.println("Calories:" + getCalories());
		System.out.println("Fat:" + getFat());
		System.out.println("Cho:" + getCholestrol());
		System.out.println("sodium:" + getSodium());
		System.out.println("Carbs:" + getCarbs());
		System.out.println("Protein:" + getProtein());
		
		
	}
	/**
	 * set default preferences for max usage per day
	 * @param nutritionAspect
	 * @return
	 */
	public void setPreference(String nutritionAspect, int value)
	{
		//Scanner prefs = new Scanner(System.in);
		//String readString = prefs.nextLine();

		/* carriage return. use default */
		//if (readString.equals("")){
		if ( nutritionAspect.equals("calories") ){
			maxCals=value;
		}
		else if ( nutritionAspect.equals("fat") ){
			fat = value;
		}
		else if ( nutritionAspect.equals("cholestrol") ){
			cholestrol = value;
		}
		else if ( nutritionAspect.equals("sodium") ){
			sodium = value;
		}
		else if ( nutritionAspect.equals("totalCarbs") ){
			totalCarbs = value;
		}
		else if ( nutritionAspect.equals("protein") ){
			protein = value;
		}
		
		fireDietaryProfileObservers(this);
		//}

		/*else 
		{    
			//number or non number entered 
			try {
				int number = Integer.parseInt(readString);
				if ( number < 0 ){
					System.out.println("Please enter an integer value greater than 0");
					input = setPreference(nutritionAspect);
				} 
				else {
					input = number;			
				}	
			}
			// non number entered 
			catch (NumberFormatException e)		
			{ 
				System.out.println("Please enter an integer value");
				input = setPreference(nutritionAspect);
			}				
		}*/
		//return input;
	}

	/** 
	 * user sets preferences 
	 */
	/*public void setDietaryPreferences(){
		System.out.println("Please enter your daily preferences below. Averages are displayed.\n");
		setCalories();
		setFat();
		setCholestrol();
		setSodium();
		setCarbs();
		setProtein();
	}*/

	/* ===================== CALORIES ===================== */	
	/* set start value */
	/*public void setCalories(){
		System.out.println("Maximum Calories[2000]: ");
		maxCals = setPreference("calories");
		startCals = maxCals;
	}*/

	/* set new value after purchase made */
	public void setCalories(int newCalories){
		maxCals = newCalories;
	}

	public int getCalories(){ 
		return maxCals; 
	}

	/*public void recalcCalories( int usedCalories ){
		int remaining = getCalories() - usedCalories;
		setCalories(remaining);
	}*/

	/* =================== SATURATED FAT ================== */
	/* set start value */
	/*public void setFat(){
		System.out.println("Saturated Fats[20]: ");
		fat = setPreference("fat");
		startFat = fat;
	}*/

	/* set new value after purchase made */
	public void setFat(int newFat){
		fat = newFat;
	}

	public int getFat() { 
		return fat; 
	}

	/*public void recalcFat( int usedFat ){
		int remaining = getFat() - usedFat;
		setFat(remaining);
	}*/

	/* ==================== CHOLESTROL ==================== */
	/* set start value */
	/*public void setCholestrol() { 
		System.out.println("Cholestrol[300]: ");
		cholestrol = setPreference("cholestrol");
		startCholestrol = cholestrol;
	}*/

	/* set new value after purchase made */
	public void setCholestrol(int newCholestrol){
		cholestrol = newCholestrol;
	}

	public int getCholestrol() { 
		return cholestrol; 
	}

	/*public void recalcCholestrol( int usedCholestrol ){
		int remaining = getCholestrol() - usedCholestrol;
		setCholestrol(remaining);
	}*/

	/* ====================== SODIUM ====================== */
	/* set start value */
	/*public void setSodium() {
		System.out.println("Sodium[2400]: ");
		sodium = setPreference("sodium");
		startSodium = sodium;
	}*/

	/* set new value after purchase made */
	public void setSodium(int newSodium){
		sodium = newSodium;
	}

	public int getSodium() { 
		return sodium; 
	}

	/*public void recalcSodium( int usedSodium ){
		int remaining = getSodium() - usedSodium;
		setSodium(remaining);
	}*/

	/* =================== CARBOHYDRATES ================== */
	/* set start value */
	/*public void setCarbs(){
		System.out.println("Total Carbohydrates[300]: ");
		totalCarbs = setPreference("totalCarbs");
		startCarbs = totalCarbs;
	}*/

	/* set new value after purchase made */
	public void setCarbs(int newCarbs){
		totalCarbs = newCarbs;
	}

	public int getCarbs() { 
		return totalCarbs; 
	}

	/*public void recalcCarbs( int usedCarbs ){
		int remaining = getCarbs() - usedCarbs;
		setCarbs(remaining);
	}*/

	/* ====================== PROTEIN ===================== */
	/* set start value */
	/*public void setProtein(){
		System.out.println("Protein[50]: ");
		protein = setPreference("protein");
		startProtein = protein;
	}*/

	/* set new value after purchase made */
	public void setProtein(int newProtein){
		protein = newProtein;
	}

	public int getProtein() { 
		return protein; 
	}
	
	public LinkedList<DietaryEntry> getDietEntries() {
		
		Collections.sort(dietaryHistory,new Comparator<DietaryEntry>() {

			@Override
			public int compare(DietaryEntry o1, DietaryEntry o2) {
				Calendar date = o1.getDate();
				Calendar date2 = o2.getDate();
				return date.compareTo(date2);
			}
		});
		return dietaryHistory;
	}

	/*public void recalcProtein( int usedProtein ){
		int remaining = getProtein() - usedProtein;
		setProtein(remaining);
	}*/

	/** 
	 * system displays user preferences and graph 
	 * with usage summary
	 */	
	/*public void displayProfile(){
		DecimalFormat percent = new DecimalFormat("000.00#%");

		// calculate usage after purchase made
		trackUsage();

		// displays preferences
		System.out.println("User Preferences for Daily Maximum " + 
				"\n                         " + "Daily Limit" 	+ "\tUsed" 	+ "\t\tPercentage"  								+
				"\n  Calories:              " + startCals 		+ "\t\t" + getCalories() 	+ "\t\t" + percent.format(usedCals/startCals) 			+
				"\n  Saturated Fat:         " + startFat 	+ "\t\t" + getFat() 		+ "\t\t" + percent.format(usedFat/startFat) 		+
				"\n  Carbohydrate:          " + startCarbs 		+ "\t\t" + getCarbs() 		+ "\t\t" + percent.format(usedCholestrol/startCholestrol)+
				"\n  Sodium:                " + startSodium 	+ "\t\t" + getSodium()		+ "\t\t" + percent.format(usedSodium/startSodium)		+
				"\n  Cholestrol:            " + startCholestrol + "\t\t" + getCholestrol() 	+ "\t\t" + percent.format(usedCarbs/startCarbs) 			+
				"\n  Protein:               " + startProtein 	+ "\t\t" + getProtein() 	+ "\t\t" + percent.format(usedProtein/startProtein) 		+
				"\n  TEST:  " + 20 	+ "\t\t" + 10 	+ "\t\t" + percent.format(10/20) 		+				"\n\n");	


		//GraphSummary usage = new GraphSummary();
		//usage.getClass();

	}*/

	/** 
	 * system tracks Preferences and usage 
	 * system checks the item selected for purchase 
	 * with dietary preferences. if limit exceeded, 
	 * returns error
	 */
	/*public void trackUsage(){
		// maxCals, fat, cholestrol, sodium, totalCarbs, protein 
		// calculates and displays percentages for usage
		//DecimalFormat percent = new DecimalFormat("0.00#%");

		usedCals = startCals - maxCals;
		//System.out.println( "Percent Calories Used:      " + percent.format(usedCals/startCals) );

		usedFat = startFat - fat;
		//System.out.println( "Percent Saturated Fat Used: " + percent.format(usedFat/startFat) );

		usedCholestrol = startCholestrol - cholestrol;
		//System.out.println( "Percent Cholestrol Used:    " + percent.format(usedCholestrol/startCholestrol) );

		usedSodium = startSodium - sodium;
		//System.out.println( "Percent Sodium Used:        " + percent.format(usedSodium/startSodium) );

		usedCarbs = startCarbs - totalCarbs;
		//System.out.println( "Percent Carbohydrates Used: " + percent.format(usedCarbs/startCarbs) );

		usedProtein = startProtein - protein;
		//System.out.println( "Percent Protein Used:       " + percent.format(usedProtein/startProtein) );
	}*/

	/**
	 *  reset usage for new day
	 */
	/*public void resetUsage(){
		usedCals = 0;
		usedFat = 0;
		usedCholestrol = 0;
		usedSodium = 0;
		usedCarbs = 0;
		usedProtein = 0;
	}*/


	/** 
	 * system updates usage after new purchase 
	 */
	/*
	public void updatePreferences(){
		recalcCalories( item.getCalories() );

		recalcFat( item.getFat().intValue() );

		recalcCholestrol( item.getCholestrol().intValue() );

		recalcSodium( item.getSodium().intValue() );

		recalcCarbs( item.getCarbs().intValue() );

		recalcProtein( item.getProtein().intValue() );

	}
	 */
	
}


